<?php


namespace app\community\oauth2\Model;


use app\cms\community\lib\QueryModel;
use app\community\oauth2\Exception\ClientException;
use app\community\oauth2\Exception\ClientNotFoundException;
use iflow\Response;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;

class oauthClientAccessTokenModel extends QueryModel
{
    protected $table = 'oauth_client_access_token_table';

    /**
     * 保存AccessToken
     * @param AccessTokenEntityInterface $accessTokenEntity
     * @return Response
     * @throws ClientException
     */
    public function saveAccessToken(AccessTokenEntityInterface $accessTokenEntity): Response
    {
        $save = $this->createData([
            'app_id' => $accessTokenEntity -> getClient() -> getIdentifier(),
            'app_access_token' => $accessTokenEntity -> getIdentifier(),
            'expired' => $accessTokenEntity -> getExpiryDateTime() -> getTimestamp(),
            'open_id' => $accessTokenEntity -> getUserIdentifier() ?: '-1',
            'app_scopes' => $accessTokenEntity -> getScopes()[0] ?? ''
        ]);
        if ($save -> data['code'] !== 200) {
            throw new ClientException($save -> data['msg'], $save -> data['code']);
        }
        return $save;
    }

    /**
     * 撤销 AccessToken
     * @param string $accessToken
     * @return Response
     */
    public function revokeAccessToken(string $accessToken): Response
    {
        return $this->deleteData([
            'app_id' => request() -> params('client_id'),
            'app_access_token' => $accessToken
        ]);
    }

    /**
     * 验证AccessToken是否过期
     * @param string $accessToken
     * @return bool
     * @throws ClientNotFoundException
     */
    public function validateAccessToken(string $accessToken): bool
    {
        $accessToken = $this->findInfo([
            'app_id' => request() -> params('client_id'),
            'app_access_token' => $accessToken
        ]);

        if (!$accessToken) {
            throw new ClientNotFoundException('Invalid AccessToken', 401);
        }

        if ($accessToken['expired'] < time()) {
            throw new ClientNotFoundException('AccessToken has expired', 401);
        }

        return false;
    }
}